package books.storage.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jws.WebService;

import books.storage.dto.BookDto;
import books.storage.dto.LiteraryGenreDto;
import books.storage.eao.BookManagerEao;
import books.storage.eao.BooksStorageEao;
import books.storage.entity.BookEntity;
import books.storage.entity.LiteraryGenreEntity;
import books.storage.exception.EntityNotFoundException;
import books.storage.exception.NotEnoughtExemplaireException;
import books.storage.util.Conversion;

/**
 * Session Bean implementation class BooksStorageEJB
 */
@Stateless
@LocalBean
@WebService
public class BooksManagerBean implements IBooksManagerBean {

	@EJB
	BooksStorageEao eao;
	@EJB
	BookManagerEao beao;
	@EJB
	Conversion conv;

	/**
	 * Default constructor.
	 */
	public BooksManagerBean() {
	}

	public BooksManagerBean(BooksStorageEao eao, BookManagerEao beao,
			Conversion conv) {
		this.eao = eao;
		this.beao = beao;
		this.conv = conv;
	}

	/*
	 * INSERT METHODS
	 */

	public LiteraryGenreDto addNewLiteraryGenre(LiteraryGenreDto _genre)
			throws EntityNotFoundException {
		LiteraryGenreEntity genre = this.conv.fromLiteraryGenreDto(_genre);
		this.eao.insertEntity(genre);
		return this.conv.fromLiteraryGenreEntity(genre);
	}

	public BookDto addNewBook(BookDto _book) throws EntityNotFoundException {
		BookEntity book = this.conv.fromBookDto(_book);
		this.eao.insertEntity(book);
		return this.conv.fromBookEntity(book);
	}

	/*
	 * DELETE METHODS
	 */

	public void deleteLiteraryGenre(LiteraryGenreDto _genre)
			throws EntityNotFoundException {
		this.eao.deleteEntity(this.conv.fromLiteraryGenreDto(_genre));
	}

	public void deleteBook(BookDto _book) throws EntityNotFoundException {
		this.eao.deleteEntity(this.conv.fromBookDto(_book));
	}

	/*
	 * UPDATE METHODS
	 */

	public LiteraryGenreDto updateLiteraryGenre(LiteraryGenreDto _genre)
			throws EntityNotFoundException {
		LiteraryGenreEntity genre = this.conv.fromLiteraryGenreDto(_genre);
		this.eao.updateEntity(genre);
		return this.conv.fromLiteraryGenreEntity(genre);
	}

	public BookDto updateBook(BookDto _book) throws EntityNotFoundException {
		BookEntity book = this.conv.fromBookDto(_book);
		this.eao.updateEntity(book);
		return this.conv.fromBookEntity(book);
	}

	public BookDto addCopies(int copiesNumber, BookDto _book)
			throws EntityNotFoundException {
		_book.addCopies(copiesNumber);
		return this.updateBook(_book);
	}

	public BookDto removeCopies(int copiesNumber, BookDto _book)
			throws EntityNotFoundException, NotEnoughtExemplaireException {
		_book.removeCopies(copiesNumber);
		return this.updateBook(_book);
	}

	/*
	 * FIND METHODS
	 */

	public LiteraryGenreDto findLiteraryGenreDto(Integer _id)
			throws EntityNotFoundException {
		return this.conv.fromLiteraryGenreEntity(this.eao.findOrFail(
				LiteraryGenreEntity.class, _id));
	}

	public BookDto findBookDto(String _ISBN) throws EntityNotFoundException {
		return this.conv.fromBookEntity(this.beao.searchBookByReference(_ISBN));
	}

	/*
	 * SELECT METHODS
	 */

	public List<BookDto> searchBookByName(String _title) {
		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : this.beao.searchBookByName(_title)) {
			books.add(this.conv.fromBookEntity(book));
		}
		return books;
	}

	public List<BookDto> searchBookBetweenEditionDates(Date _first, Date _second) {
		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : this.beao.searchBookBetweenEditionDates(_first,
				_second)) {
			books.add(this.conv.fromBookEntity(book));
		}
		return books;
	}

	public List<BookDto> searchBookByLiteraryGenre(String _genreName) {
		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : this.beao.searchBookByLiteraryGenre(_genreName)) {
			books.add(this.conv.fromBookEntity(book));
		}
		return books;
	}

	public List<BookDto> searchBookByAuthor(String _name) {
		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : this.beao.searchBookByAuthor(_name)) {
			books.add(this.conv.fromBookEntity(book));
		}
		return books;
	}

	/*
	 * GET ALL
	 */

	public List<BookDto> findAllBooks() {
		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : this.eao.getAllEntities(BookEntity.class)) {
			books.add(this.conv.fromBookEntity(book));
		}
		return books;
	}

	public List<LiteraryGenreDto> findAllGenre() {
		List<LiteraryGenreDto> genres = new ArrayList<>();
		for (LiteraryGenreEntity genre : this.eao
				.getAllEntities(LiteraryGenreEntity.class)) {
			genres.add(this.conv.fromLiteraryGenreEntity(genre));
		}
		return genres;
	}
}
